﻿// TestClient.MainPage.xaml.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.html)
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       MainPage.xaml.cs
// Author:     HSS\gbanta
// Created:    07/16/2011
// Modified:   07/16/2011
// ----------------------------------------------------------------------------
namespace TestClient
{
	#region Using Directives
	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.Diagnostics;
	using System.IO;
	using System.Linq;
	using System.Windows;
	using System.Windows.Controls;
	using System.Windows.Media;
	using System.Windows.Media.Animation;
	using System.Windows.Media.Imaging;
	using System.Windows.Resources;
	using HSS.Interlink;
	using TestClient.Web;
	using System.Windows.Threading;
	#endregion

	#region MainPage
	/// <summary>
	/// HSS Interlink TestClient MainPage.
	/// </summary>
	public partial class MainPage : UserControl
	{
		#region Fields
		/// <summary>
		/// NOTE: Not the recommended approach; demo purposes only.
		/// Dictionary containing the custom metadata for each file to be uploaded.
		/// </summary>
		public static Dictionary<string, CustomMetadata> Metadata = new Dictionary<string, CustomMetadata>();
		bool isExpanded = true;
		bool refreshing;
		int filesDeletedCount = 0;
		int totalCount = 0;
		ObservableCollection<InterlinkFile> files;
		MainPageViewModel viewModel;
		Queue<InterlinkFile> deleteFileQueue;
		Queue<FileInfo> droppedFilesQueue = new Queue<FileInfo>();
		DispatcherTimer timer;
		static MainPage current;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		public MainPage()
		{
			current = this;
			InitializeComponent();

			VisualStateManager.GoToState(this, "SideA", false);

			this.viewModel = new MainPageViewModel();
			this.viewModel.Files.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Files_CollectionChanged);
			this.DataContext = this.viewModel;

			// Register a handler for Rendering events
			CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

			this.LayoutRoot.MouseRightButtonDown += (s, e) =>
				{
					e.Handled = true;
				};

			TimeSpan tsrefresh = TimeSpan.FromSeconds(30);
			this.timer = new DispatcherTimer();
			this.timer.Interval = TimeSpan.FromSeconds(1);
			this.timer.Tick += (s, e) =>
				{
					if (this.timer.Interval != tsrefresh)
						this.timer.Interval = tsrefresh;
					this.RefreshFileList();
				};

			this.Loaded += (s, e) =>
				{
					#region Loaded

					#region Get default values
					this.chkMultiselect.IsChecked = udialog.AllowMultiselect;
					this.chkAutoUpload.IsChecked = udialog.AutoUpload;
					this.chkAllowFileOverwrite.IsChecked = udialog.AllowFileOverwrite;
					this.chkAutoClose.IsChecked = udialog.AutoClose;
					this.chkAllowNewUpload.IsChecked = udialog.AllowNewUpload;
					this.chkShowTitleImage.IsChecked = udialog.IsTitleImageVisible;
					this.txtTitle.Text = udialog.Title.ToString();
					this.txtFolderName.Text = udialog.FolderName;
					this.txtComment.Text = udialog.Comment;
					this.txtExcluded.Text = udialog.ExcludeFileExtension;
					this.txtFilter.Text = udialog.Filters;
					this.cboMaxConcurrent.SelectedItem = udialog.MaxConcurrentUploads;
					this.cboMaxFileSize.ItemsSource = MaxFileSize.MaxFileSizes;
					this.cboMaxFileSize.SelectedIndex = 2; // 1MB
					this.txtNoFileText.Text = udialog.NoFilesText;
					if (System.Windows.Application.Current.IsRunningOutOfBrowser)
					{
						var b = new UriBuilder("http", "localhost", 15406, udialog.UploadUri);
						udialog.UploadUri = b.ToString();
					}

					this.txtTitleDownload.Text = DownloadFileDialog.DefaultTitle;
					this.chkShowTitleImageDownload.IsChecked = true;

					#endregion

					#region Show sample code/xaml
					StreamResourceInfo info = Application.GetResourceStream(new Uri("TestClient;component/SourceXaml.txt", UriKind.Relative));
					if (null != info)
					{
						using (StreamReader sr = new StreamReader(info.Stream))
							this.sampleCodeXaml.Text = sr.ReadToEnd();
						info.Stream.Close();
						info = null;
					}
					info = Application.GetResourceStream(new Uri("TestClient;component/SourceCSharp.txt", UriKind.Relative));
					if (null != info)
					{
						using (StreamReader sr = new StreamReader(info.Stream))
							this.sampleCodeCSharp.Text = sr.ReadToEnd();
						info.Stream.Close();
						info = null;
					}
					#endregion

					this.lstDemos.SelectionChanged += new SelectionChangedEventHandler(lstDemos_SelectionChanged);
					this.cboBackground.SelectionChanged += new SelectionChangedEventHandler(cboBackground_SelectionChanged);
					this.cboBackgroundDownload.SelectionChanged += new SelectionChangedEventHandler(cboBackgroundDownload_SelectionChanged);

					this.timer.Start();

					#endregion
				};
		}
		#endregion

		#region Properties

		#region SourceHeight
		/// <summary>
		/// Gets or sets the height of the source code viewer.
		/// </summary>
		public double SourceHeight
		{
			get { return (double)GetValue(SourceHeightProperty); }
			set { SetValue(SourceHeightProperty, value); }
		}
		/// <summary>
		/// Using a DependencyProperty as the backing store for SourceHeight.  This enables animation, styling, binding, etc...
		/// </summary>
		public static readonly DependencyProperty SourceHeightProperty =
			DependencyProperty.Register("SourceHeight", typeof(double), typeof(MainPage), new PropertyMetadata(50D, SourceHeightChanged));
		static void SourceHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			MainPage page = d as MainPage;
			if (null != page && null != page.sourceCodeRow)
				page.sourceCodeRow.Height = new GridLength((double)e.NewValue);
		}
		#endregion

		#endregion

		#region Methods

		static string GetMetadata(UploadFileViewModel file)
		{
			#region Metadata for CustomFileDetail on the Upload Demo
			CustomMetadata metadata;
			if (MainPage.Metadata.TryGetValue(file.FileName, out metadata))
			{
				if (null != metadata)
					return metadata.Tag + "," + metadata.Comment;
			}
			#endregion

			#region Metadata for the DragDrop Demo
			DraggedFileView dragFile = current.viewModel.Files.FirstOrDefault(f => f.FileName == file.FileName);
			if (null != dragFile && (
				!string.IsNullOrEmpty(dragFile.FileTag) ||
				!string.IsNullOrEmpty(dragFile.FileComment)))
			{
				return dragFile.FileTag + "," + dragFile.FileComment;
			}
			#endregion

			return string.Empty;
		}

		private static readonly UploadFileDialog udialog = new UploadFileDialog(GetMetadata);

		void ShowUploadDialog(IEnumerable<FileInfo> files, bool selectShow)
		{

			udialog.AllowMultiselect = this.chkMultiselect.IsChecked.Value;
			udialog.AllowFileOverwrite = this.chkAllowFileOverwrite.IsChecked.Value;
			udialog.AutoUpload = this.chkAutoUpload.IsChecked.Value;
			udialog.AutoClose = this.chkAutoClose.IsChecked.Value;
			udialog.AllowNewUpload = this.chkAllowNewUpload.IsChecked.Value;
			udialog.IsTitleImageVisible = this.chkShowTitleImage.IsChecked.Value;
			udialog.Title = this.txtTitle.Text;
			udialog.FolderName = this.txtFolderName.Text;
			udialog.Comment = this.txtComment.Text;
			udialog.ExcludeFileExtension = this.txtExcluded.Text;
			udialog.Filters = this.txtFilter.Text;
			udialog.MaxConcurrentUploads = int.Parse(((ComboBoxItem)this.cboMaxConcurrent.SelectedItem).Content.ToString());
			udialog.MaxFileSizeKB = ((MaxFileSize)this.cboMaxFileSize.SelectedItem).Bytes;
			udialog.NoFilesText = this.txtNoFileText.Text;
			if (this.chkUseCustomDetail.IsChecked.Value)
				udialog.ViewFileDetail = ViewDetail;
			string hexColorString = ((ComboBoxItem)this.cboBackground.SelectedItem).Tag.ToString();
			udialog.Background = this.GetColoredBrushFromHexString(hexColorString);

			udialog.FileUploaded += new EventHandler<FileUploadCompletedEventArgs>(udialog_FileUploaded);
			udialog.Completed += new EventHandler<UploadCompletedEventArgs>(udialog_Completed);
			udialog.Closed += new EventHandler(udialog_Closed);

			if (null == files)
			{
				if (selectShow)
					udialog.BrowseAndShow();
				else
					udialog.Show();
			}
			else
				udialog.Show(files);
		}

		ChildWindow ViewDetail(UploadFileViewModel file)
		{
			var window = new CustomFileDetail(file);
			window.Show();
			return window;
		}
		void RefreshFileList()
		{
			if (refreshing)
				return;
			refreshing = true;
			TestClient.Web.FileAccessServiceClient svc = new Web.FileAccessServiceClient();
			svc.GetFileListCompleted += (s, e) =>
			{
				try
				{
					if (e.Cancelled)
						return;

					if (null != e.Error)
					{
						MessageBox.Show(e.Error.Message);
						return;
					}

					files = e.Result;
					if (null != this.files)
					{
						bool hasFiles = this.files.Count > 0;
						this.btnDelete.IsEnabled = hasFiles;
						this.btnDownload.IsEnabled = hasFiles;
						this.btnDownloadMultiple.IsEnabled = hasFiles;
						this.btnOpen.IsEnabled = hasFiles;
						this.btnOpenAsAttachment.IsEnabled = hasFiles;
					}
					else
					{
						this.btnDelete.IsEnabled = false;
						this.btnDownload.IsEnabled = false;
						this.btnDownloadMultiple.IsEnabled = false;
						this.btnOpen.IsEnabled = false;
						this.btnOpenAsAttachment.IsEnabled = false;
					}
					this.dtgFiles.ItemsSource = this.files;
					if (this.files.Count > 0)
						this.dtgFiles.SelectedIndex = 0;

				}
				catch (Exception ex)
				{
					MessageBox.Show(ex.Message);
				}
				finally
				{
					refreshing = false;
					this.refreshBusy.IsBusy = false;
				}
			};
			svc.GetFileListAsync();
			this.refreshBusy.IsBusy = true;
		}
		void Expand()
		{
			DoubleAnimation da = new DoubleAnimation();
			da.Duration = new Duration(TimeSpan.FromMilliseconds(300));
			da.From = this.sourceCodeRow.Height.Value;
			da.To = this.ActualHeight * 0.5;

			Storyboard.SetTarget(da, this);
			Storyboard.SetTargetProperty(da, new PropertyPath("SourceHeight"));

			Storyboard sb = new Storyboard();
			sb.Completed += (s, e) =>
				{
					this.imgExpando.Source = new BitmapImage(new Uri("assets/collapse.png", UriKind.Relative));
					this.isExpanded = true;
				};
			sb.Children.Add(da);
			sb.Begin();
		}
		void Collapse()
		{
			DoubleAnimation da = new DoubleAnimation();
			da.Duration = new Duration(TimeSpan.FromMilliseconds(300));
			da.From = this.sourceCodeRow.Height.Value;
			da.To = 50;

			Storyboard.SetTarget(da, this);
			Storyboard.SetTargetProperty(da, new PropertyPath("SourceHeight"));

			Storyboard sb = new Storyboard();
			sb.Completed += (s, e) =>
				{
					this.imgExpando.Source = new BitmapImage(new Uri("assets/expand.png", UriKind.Relative));
					this.isExpanded = false;
				};
			sb.Children.Add(da);
			sb.Begin();
		}
		void DownloadFile()
		{
			if (null == this.dtgFiles.SelectedItem)
				return;

			if (this.dtgFiles.SelectedItems.Count > 1)
				MessageBox.Show("You have more than one file selected, only the first file will be downloaded.", "HSS Interlink", MessageBoxButton.OK);

			TestClient.Web.InterlinkFile file = this.dtgFiles.SelectedItem as TestClient.Web.InterlinkFile;
			if (null == file)
				return;
			string ext = Path.GetExtension(file.FileName);

			SaveFileDialog saveFileDialog = new SaveFileDialog();
			try
			{
				saveFileDialog.Filter = "All files (*.*)|*.*|File (*" + ext + ")|*" + ext;
				saveFileDialog.FilterIndex = 2;
				DownloadFileDialog ddialog = null;
				if (saveFileDialog.ShowDialog() == true)
				{
					string hexColorString = ((ComboBoxItem)this.cboBackgroundDownload.SelectedItem).Tag.ToString();
					ddialog = new DownloadFileDialog(saveFileDialog.SafeFileName, saveFileDialog.OpenFile(), file.FileName);
					ddialog.Title = this.txtTitleDownload.Text;
					ddialog.IsTitleImageVisible = this.chkShowTitleImageDownload.IsChecked.Value;
					ddialog.Background = this.GetColoredBrushFromHexString(hexColorString);
					ddialog.Show();
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				Debug.WriteLine(ex.ToString());
			}
		}
		void DownloadMultiple()
		{
			if (null == this.dtgFiles.SelectedItems)
				return;

			var files = this.dtgFiles.SelectedItems.OfType<TestClient.Web.InterlinkFile>().Select(f => f.FileName);
			if (files.Count() == 0)
				return;

			SaveFileDialog dialog = new SaveFileDialog()
				{
					Filter = "Compressed (zipped) Folder (*.zip)|*.zip",
					DefaultExt = "*.zip"
				};
			try
			{
				DownloadFileDialog ddialog = null;
				if (dialog.ShowDialog() == true)
				{
					string hexColorString = ((ComboBoxItem)this.cboBackgroundDownload.SelectedItem).Tag.ToString();
					ddialog = new DownloadFileDialog(dialog.SafeFileName, dialog.OpenFile(), files.ToArray());
					ddialog.Title = this.txtTitleDownload.Text;
					ddialog.IsTitleImageVisible = this.chkShowTitleImageDownload.IsChecked.Value;
					ddialog.Background = this.GetColoredBrushFromHexString(hexColorString);
					ddialog.Show();
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				Debug.WriteLine(ex.ToString());
			}
		}
		void DeleteFile()
		{
			try
			{
				if (this.dtgFiles.SelectedItems.Count > 1)
				{
					this.DeleteSelectedFiles();
					return;
				}

				if (null == this.dtgFiles.SelectedItem)
				{
					if (this.files.Count > 0)
						MessageBox.Show("Please select a file to delete.");
				}
				else
				{
					if (MessageBox.Show("Are you sure you want to delete the select file?", "Delete File", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
					{
						this.btnDelete.IsEnabled = false;

						InterlinkFile file = this.dtgFiles.SelectedItem as InterlinkFile;
						if (null == file)
							return;

						TestClient.Web.FileAccessServiceClient svc = new Web.FileAccessServiceClient();
						svc.DeleteFileCompleted += (s, args) =>
						{
							if (!args.Cancelled)
							{
								if (null != args.Error)
									MessageBox.Show(args.Error.Message);
								else
								{
									if (args.Result)
										this.files.Remove(args.UserState as InterlinkFile);
									this.btnDelete.IsEnabled = this.files.Count > 0;
									this.btnDownload.IsEnabled = this.files.Count > 0;
									this.btnDownloadMultiple.IsEnabled = this.files.Count > 0;
									this.btnOpen.IsEnabled = this.files.Count > 0;
									this.btnOpenAsAttachment.IsEnabled = this.files.Count > 0;
								}
							}
						};
						svc.DeleteFileAsync(file.FileName, file);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}
		void DeleteSelectedFiles()
		{
			try
			{
				IList selectedFiles = this.dtgFiles.SelectedItems;
				if (null == selectedFiles)
				{
					if (this.files.Count > 0)
						MessageBox.Show("Please select one ore more files to delete.");
				}
				else
				{
					if (MessageBox.Show("Are you sure you want to delete the [ " + selectedFiles.Count + " ] select files?", "Delete Files", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
					{
						this.btnDelete.IsEnabled = false;
						deleteFileQueue = new Queue<InterlinkFile>();
						foreach (InterlinkFile file in selectedFiles)
							deleteFileQueue.Enqueue(file);
						this.ProcessDeleteQueue();
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}
		void ProcessDeleteQueue()
		{
			if (this.deleteFileQueue.Count > 0)
			{
				if (totalCount == 0)
					totalCount = this.deleteFileQueue.Count;
				InterlinkFile currentFile = this.deleteFileQueue.Dequeue();

				TestClient.Web.FileAccessServiceClient svc = new Web.FileAccessServiceClient();
				svc.DeleteFileCompleted += (s, args) =>
				{
					if (args.Cancelled)
					{
						this.deleteFileQueue.Clear();
						this.deleteFileQueue = null;
						MessageBox.Show("Errors encountered; canceling delete request.");
						return;
					}

					if (null != args.Error)
					{
						this.deleteFileQueue.Clear();
						this.deleteFileQueue = null;
						MessageBox.Show("Errors encountered; canceling delete request.\r\n" + args.Error.Message);
						return;
					}

					if (!args.Result)
					{
						this.deleteFileQueue.Clear();
						this.deleteFileQueue = null;
						InterlinkFile failedFile = args.UserState as InterlinkFile;
						if (null != failedFile)
							MessageBox.Show("Failed to delete file [ " + failedFile.FileName + " ]; canceling delete request.");
						else
							MessageBox.Show("Failed to delete a file ; canceling delete request.");
						return;
					}

					filesDeletedCount++;

					// Continue processing
					this.ProcessDeleteQueue();

				};
				svc.DeleteFileAsync(currentFile.FileName, currentFile);
			}
			else
			{
				this.deleteFileQueue.Clear();
				this.deleteFileQueue = null;
				this.RefreshFileList();
			}
		}
		void CreatePhoto(FileInfo fi)
		{
			using (Stream stream = fi.OpenRead())
			{
				try
				{
					// Decode the image bits
					BitmapImage bi = null;

					try
					{
						bi = new BitmapImage();
						bi.SetSource(stream);
					}
					catch (OutOfMemoryException)
					{
						// Just in case
						droppedFilesQueue.Clear();
						MessageBox.Show("Out of memory");
						return;
					}
					catch (Exception)
					{
						// Probably came here because the image isn't valid; ignore
						return;
					}

					// Compute the image dimensions
					double cx = (double)bi.PixelWidth;
					double cy = (double)bi.PixelHeight;


					if (cx >= cy)
					{
						// Set width to 100 and compute height
						cy *= 100.0 / cx;
						cx = 100.0;
					}
					else
					{
						// Set width to 100 and compute height
						cy *= 100.0 / cx;
						cx = 100.0;
					}

					// Create a WriteableBitmap the same size as the image to be displayed
					Image image = new Image();
					image.Source = bi;

					WriteableBitmap wb1 = new WriteableBitmap((int)cx, (int)cy);
					ScaleTransform transform = new ScaleTransform();
					transform.ScaleX = cx / bi.PixelWidth;
					transform.ScaleY = cy / bi.PixelHeight;
					wb1.Render(image, transform);
					wb1.Invalidate();

					// Now make a copy of the WriteableBitmap so the BitmapImage can be garbage-collected (important!)
					WriteableBitmap wb2 = new WriteableBitmap((int)cx, (int)cy);
					for (int i = 0; i < wb2.Pixels.Length; i++)
						wb2.Pixels[i] = wb1.Pixels[i];
					wb2.Invalidate();

					wb1 = null;
					bi = null;

					DraggedFileView fileView = DraggedFileView.Create(fi, wb2, this.viewModel);
					this.viewModel.Files.Add(fileView);
					fileView.Visibility = System.Windows.Visibility.Visible;
				}
				catch (Exception)
				{
					// Ignore exceptions resulting from drops of non-image files
				}
			}
		}
		SolidColorBrush GetColoredBrushFromHexString(string hexColorString)
		{
			return new SolidColorBrush(Color.FromArgb(
											Convert.ToByte(hexColorString.Substring(1, 2), 16),
											Convert.ToByte(hexColorString.Substring(3, 2), 16),
											Convert.ToByte(hexColorString.Substring(5, 2), 16),
											Convert.ToByte(hexColorString.Substring(7, 2), 16)));
		}
		#endregion

		#region Event Handlers
		void CompositionTarget_Rendering(Object sender, EventArgs e)
		{
			if (droppedFilesQueue.Count != 0)
			{
				// Create a photo
				FileInfo fi = droppedFilesQueue.Dequeue();
				CreatePhoto(fi);
			}
		}
		void PreShow_Click(object sender, RoutedEventArgs e)
		{
			var dialog = new OpenFileDialog();
			dialog.Multiselect = this.chkMultiselect.IsChecked.Value;
			dialog.Filter = this.txtFilter.Text;
			try
			{
				if (dialog.ShowDialog() == true)
					this.ShowUploadDialog(dialog.Files, false);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				Debug.WriteLine(ex.ToString());
			}
		}
		void btnSelectShow_Click(object sender, RoutedEventArgs e)
		{
			this.ShowUploadDialog(null, true);
		}
		void Show_Click(object sender, RoutedEventArgs e)
		{
			this.ShowUploadDialog(null, false);
		}
		void btnDownload_Click(object sender, RoutedEventArgs e)
		{
			this.DownloadFile();
		}
		void btnDownloadMultiple_Click(object sender, RoutedEventArgs e)
		{
			this.DownloadMultiple();
		}
		void btnOpen_Click(object sender, RoutedEventArgs e)
		{
			if (null == this.dtgFiles.SelectedItem)
				return;
			TestClient.Web.InterlinkFile file = this.dtgFiles.SelectedItem as TestClient.Web.InterlinkFile;
			if (null == file)
				return;
			DownloadFileDialog.OpenFileInline("filedownload.ashx",file.FileName);
		}
		void btnOpenAsAttachment_Click(object sender, RoutedEventArgs e)
		{
			if (null == this.dtgFiles.SelectedItem)
				return;
			TestClient.Web.InterlinkFile file = this.dtgFiles.SelectedItem as TestClient.Web.InterlinkFile;
			if (null == file)
				return;
			DownloadFileDialog.OpenFileAsAttachment("http://localhost/interlink/filedownload.ashx", file.FileName);
		}
		void btnRefresh_Click(object sender, RoutedEventArgs e)
		{
			this.RefreshFileList();
		}
		void btnDelete_Click(object sender, RoutedEventArgs e)
		{
			this.DeleteFile();
		}
		void lstDemos_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			if (null != e.AddedItems && e.AddedItems.Count > 0)
			{
				ListBoxItem item = e.AddedItems[0] as ListBoxItem;
				int index = int.Parse(item.Tag.ToString());

				switch (index)
				{
					case 0:
						VisualStateManager.GoToState(this, "SideB", true);
						break;

					case 1:
						VisualStateManager.GoToState(this, "SideA", true);
						break;
				}

			}
		}
		void dtgFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			if (this.dtgFiles.SelectedItems.Count > 0)
			{
				if (this.dtgFiles.SelectedItems.Count > 1)
				{
					this.btnDownload.IsEnabled = false;
					this.btnOpen.IsEnabled = false;
					this.btnOpenAsAttachment.IsEnabled = false;
					this.btnDownloadMultiple.IsEnabled = true;
				}
				else
				{
					this.btnDownload.IsEnabled = true;
					this.btnOpen.IsEnabled = true;
					this.btnOpenAsAttachment.IsEnabled = true;
					this.btnDownloadMultiple.IsEnabled = false;
				}
				this.btnDelete.IsEnabled = true;
			}
			else
			{
				this.btnDownload.IsEnabled = false;
				this.btnOpen.IsEnabled = false;
				this.btnOpenAsAttachment.IsEnabled = false;
				this.btnDelete.IsEnabled = false;
				this.btnDownloadMultiple.IsEnabled = false;
			}
		}
		void cboBackground_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			string hexColorString = ((ComboBoxItem)this.cboBackground.SelectedItem).Tag.ToString();
			this.SelectColorUpload.Background =
				new System.Windows.Media.SolidColorBrush(Color.FromArgb(
					Convert.ToByte(hexColorString.Substring(1, 2), 16),
					Convert.ToByte(hexColorString.Substring(3, 2), 16),
					Convert.ToByte(hexColorString.Substring(5, 2), 16),
					Convert.ToByte(hexColorString.Substring(7, 2), 16)));
		}
		void cboBackgroundDownload_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			string hexColorString = ((ComboBoxItem)this.cboBackgroundDownload.SelectedItem).Tag.ToString();
			this.SelectColorDownload.Background =
				new System.Windows.Media.SolidColorBrush(Color.FromArgb(
					Convert.ToByte(hexColorString.Substring(1, 2), 16),
					Convert.ToByte(hexColorString.Substring(3, 2), 16),
					Convert.ToByte(hexColorString.Substring(5, 2), 16),
					Convert.ToByte(hexColorString.Substring(7, 2), 16)));
		}
		void btnExpandSource_Click(object sender, RoutedEventArgs e)
		{
			if (!isExpanded)
				this.Expand();
			else
				this.Collapse();
		}
		void stpXamlTab_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (sourceCodeRow.Height.Value == 50)
				this.Expand();
		}
		void stpCSharpTab_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (sourceCodeRow.Height.Value == 50)
				this.Expand();
		}
		void stpUploadSettingsTab_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (sourceCodeRow.Height.Value == 50)
				this.Expand();
		}
		void stpDownloadSettingsTab_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (sourceCodeRow.Height.Value == 50)
				this.Expand();
		}
		void btnFullScreen_Click(object sender, RoutedEventArgs e)
		{
			Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
		}
		void DropZone_Drop(object sender, DragEventArgs e)
		{
			if (null == e.Data)
				return;
			if (e.Data.GetDataPresent(DataFormats.FileDrop))
			{
				FileInfo[] droppedFiles = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];
				foreach (var file in droppedFiles)
				{
					if (file.Extension.Equals(".png", StringComparison.OrdinalIgnoreCase) ||
						file.Extension.Equals(".jpg", StringComparison.OrdinalIgnoreCase))
						this.droppedFilesQueue.Enqueue(file); // DraggedFileView.Create(file, this.viewModel);
					else
						MessageBox.Show("The file [ " + file.Name + " ] is not a picture. Only .jpg or .png files allowed.");
				}
			}
		}
		void Files_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			if (this.viewModel.Files.Count > 0)
			{
				this.txtDropFileHere.Visibility = System.Windows.Visibility.Collapsed;
				this.btnPublish.IsEnabled = true;
				this.btnClearAll.IsEnabled = true;
			}
			else
			{
				this.txtDropFileHere.Visibility = System.Windows.Visibility.Visible;
				this.btnPublish.IsEnabled = false;
				this.btnClearAll.IsEnabled = false;
			}
		}
		void btnPublish_Click(object sender, RoutedEventArgs e)
		{
			var files = this.viewModel.Files.Select(f => f.file);
			this.ShowUploadDialog(files, false);
		}
		void btnClearAll_Click(object sender, RoutedEventArgs e)
		{
			this.viewModel.Files.Clear();
		}
		void btnDragDropBrowse_Click(object sender, RoutedEventArgs e)
		{
			OpenFileDialog dialog = new OpenFileDialog();
			dialog.Multiselect = this.chkMultiselect.IsChecked.Value;
			dialog.Filter = "All Image files (*.png, *.jpg)|*.png;*.jpg";
			try
			{
				if (dialog.ShowDialog() == true)
				{
					foreach (var file in dialog.Files)
					{
						if (file.Extension.Equals(".png", StringComparison.OrdinalIgnoreCase) ||
							file.Extension.Equals(".jpg", StringComparison.OrdinalIgnoreCase))
							this.droppedFilesQueue.Enqueue(file); // DraggedFileView.Create(file, this.viewModel);
						else
							MessageBox.Show("The file [ " + file.Name + " ] is not a picture. Only .jpg or .png files allowed.");
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
				Debug.WriteLine(ex.ToString());
			}
		}
		void udialog_FileUploaded(object sender, FileUploadCompletedEventArgs e)
		{
			Debug.WriteLine("File uploaded: [ " + e.FileName + " ] Result: " + e.Result);
			var file = this.viewModel.Files.FirstOrDefault(f => f.FileName == e.FileName);
			if (null != file)
				this.viewModel.Files.Remove(file);
		}
		void udialog_Completed(object sender, UploadCompletedEventArgs e)
		{
			var dialog = sender as UploadFileDialog;
			dialog.Completed -= new EventHandler<UploadCompletedEventArgs>(udialog_Completed);
			dialog.FileUploaded -= new EventHandler<FileUploadCompletedEventArgs>(udialog_FileUploaded);
		}
		void udialog_Closed(object sender, EventArgs e)
		{
			var dialog = sender as UploadFileDialog;
			dialog.Closed -= new EventHandler(udialog_Closed);
			this.RefreshFileList();
		}
		void chkAutoRefresh_Checked(object sender, RoutedEventArgs e)
		{
			if (null != this.timer)
				this.timer.Start();
		}
		void chkAutoRefresh_Unchecked(object sender, RoutedEventArgs e)
		{
			this.timer.Stop();

		}
		#endregion
	}
	#endregion

	#region MainPageViewModel
	/// <summary>
	/// MainPage ViewModel
	/// </summary>
	public class MainPageViewModel
	{
		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		public MainPageViewModel()
		{
			this.Files = new ObservableCollection<DraggedFileView>();
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets the collection of drag-dropped files.
		/// </summary>
		public ObservableCollection<DraggedFileView> Files
		{
			get;
			set;
		}
		#endregion
	}
	#endregion

	#region CustomMetadata
	/// <summary>
	/// CustomMetadata for user provided information. 
	/// </summary>
	public class CustomMetadata
	{
		public CustomMetadata()
		{

		}

		public string Tag { get; set; }
		public string Comment { get; set; }
	}
	#endregion
}